import sys
sys.path.append("..")
import pyrtl
from  pyrtl import GPUSim
import or1200_definitions

dw = or1200_definitions.OR1200_OPERAND_WIDTH
aw = or1200_definitions.OR1200_OPERAND_WIDTH

class Or1200Du(object):
    def __init__(self):
        self.rst = pyrtl.Input(bitwidth=1) #, name='rst')
        self.dcpu_cycstb_i = pyrtl.Input(bitwidth=1) #, name='dcpu_cycstb_i')
        self.dcpu_we_i = pyrtl.Input(bitwidth=1) #, name='dcpu_we_i')
        self.dcpu_adr_i = pyrtl.Input(bitwidth=32) #, name='dcpu_adr_i')
        self.dcpu_dat_lsu = pyrtl.Input(bitwidth=32) #, name='dcpu_dat_lsu')
        self.dcpu_dat_dc = pyrtl.Input(bitwidth=32) #, name='dcpu_dat_dc')
        self.icpu_cycstb_i = pyrtl.Input(bitwidth=or1200_definitions.OR1200_FETCHOP_WIDTH) #, name='icpu_cycstb_i')
        self.ex_freeze = pyrtl.Input(bitwidth=1) #, name='exfreeze')
        self.branch_op = pyrtl.Input(bitwidth=or1200_definitions.OR1200_BRANCHOP_WIDTH) #, name='branch_op')
        self.ex_insn = pyrtl.Input(bitwidth=dw) #, name='ex_insn')
        self.id_pc = pyrtl.Input(bitwidth=32) #, name='id_pc')
        self.spr_dat_npc = pyrtl.Input(bitwidth=32) #, name='spr_dat_npc')
        self.rf_dataw = pyrtl.Input(bitwidth=32) #, name='rf_dataw')

        self.du_dsr = pyrtl.Output(bitwidth=or1200_definitions.OR1200_DU_DSR_WIDTH) #, name='du_dsr')
        self.du_stall = pyrtl.Output(bitwidth=1) #, name='du_stall')
        self.du_addr = pyrtl.Output(bitwidth=aw) #, name='du_addr')

        self.du_dat_i = pyrtl.Input(bitwidth=dw) #, name='du_dat_i')

        self.du_dat_o = pyrtl.Output(bitwidth=dw) #, name='du_dat_o')
        self.du_read = pyrtl.Output(bitwidth=1) #, name='du_read')
        self.du_write = pyrtl.Output(bitwidth=1) #, name='du_write')

        self.du_except = pyrtl.Input(bitwidth=12) #, name='du_except')

        self.du_hwbkpt = pyrtl.Output(bitwidth=1) #, name='du_hwbkpt')

        self.spr_cs = pyrtl.Input(bitwidth=1) #, name='spr_cs')
        self.spr_write = pyrtl.Input(bitwidth=1) #, name='spr_write')
        self.spr_addr = pyrtl.Input(bitwidth=aw) #, name='spr_addr')
        self.spr_dat_i = pyrtl.Input(bitwidth=aw) #, name='spr_dat_i')

        self.spr_dat_o = pyrtl.Output(bitwidth=dw) #, name='spr_dat_o')

        # External Debug Interface
        self.dbg_stall_i = pyrtl.Input(bitwidth=1) #, name='dbg_stall_i')
        self.dbg_ewt_i = pyrtl.Input(bitwidth=1) #, name='dbg_ewt_i')
        self.dbg_lss_o = pyrtl.Output(bitwidth=4) #, name='dbg_lss_o')
        self.dbg_is_o = pyrtl.Output(bitwidth=2) #, name='dbg_is_o')
        self.dbg_wp_o = pyrtl.Output(bitwidth=11) #, name='dbg_wp_o')
        self.dbg_bp_o = pyrtl.Output(bitwidth=1) #, name='dbg_bp_o')
        self.dbg_stb_i = pyrtl.Input(bitwidth=1) #, name='dbg_stb_i')
        self.dbg_we_i = pyrtl.Input(bitwidth=1) #, name='dbg_we_i')
        self.dbg_adr_i = pyrtl.Input(bitwidth=aw) #, name='dbg_adr_i')
        self.dbg_dat_i = pyrtl.Input(bitwidth=dw) #, name='dbg_dat_i')
        self.dbg_dat_o = pyrtl.Output(bitwidth=dw) #, name='dbg_dat_o')
        self.dbg_ack_o = pyrtl.Output(bitwidth=1) #, name='dbg_ack_o')

        self.dbg_lss_o <<= pyrtl.Const(0b0000, bitwidth=4)
        self.dbg_is_o = pyrtl.Register(bitwidth=2) #, name='dbg_is_o')

        # connection
        showInsnAct = ShowInsnAct()


# Show insn activity (temp, must be removed)
class ShowInsnAct(object):
    def __init__(self):
        self.dbg_is_o = pyrtl.Output(bitwidth=2) #, name='dbg_is_o')
        self.ex_freeze = pyrtl.Input(bitwidth=1) #, name='exfreeze')



if __name__ == '__main__':
    or1200Du = Or1200Du()
    sim = pyrtl.GPUSim_now.GPUSim(65536)
    sim.create_dll('du.cu')
    print(pyrtl.working_block())
    ff = open("D:\work_doc\PyRTL\examples\Opencore\or1200_du.c", 'w')
    essent = pyrtl.ESSENT()
    essent._create_code(lambda s: ff.write(s + '\n'))
    ff.close()
